package agent

import (
	"booking/common/handler"
	"context"
	"encoding/json"
	"fmt"
	"regexp"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	openai "github.com/openai/openai-go/v2"
	"github.com/openai/openai-go/v2/option"
	"github.com/spf13/viper"
	"github.com/volcengine/volcengine-go-sdk/service/arkruntime"
	"github.com/volcengine/volcengine-go-sdk/service/arkruntime/model"
	"github.com/volcengine/volcengine-go-sdk/volcengine"
)

// 请求体
type ExtractRequest struct {
	Text string `json:"text,omitempty"`
}

// 解析结果结构
type Extract struct {
	ConsigneeCity    string `json:"consignee_city"`
	Source           string `json:"source"`
	Amount           string `json:"amount"`
	Courier          string `json:"courier"`
	ProductDesc      string `json:"product_desc"`
	Quantity         string `json:"quantity"`
	RecipientAddress string `json:"recipient_address"`
	RecipientName    string `json:"recipient_name"`
	RecipientPhone   string `json:"recipient_phone"`
}

// 系统提示词
const systemPrompt = `你是一个订单信息提取专家。你需要从用户输入的订单描述文本中提取结构化信息。

提取规则：
1. 城市（consignee_city）：北京、上海等地名
2. 来源（source）：美团、京东等平台名称
3. 金额（amount）：纯数字，如78、147、235 返回类型为string类型
4. 快递（courier）：顺丰、申通、韵达等快递公司
5. 产品描述（product_desc）：章印、备案、刻章等服务描述
6. 数量（quantity）：从产品描述中提取数量，如"2枚"提取为2，默认为1 返回类型为string类型
7. 收货地址（recipient_address）：详细地址，不包含姓名和电话
8. 收货人姓名（recipient_name）：联系人姓名
9. 收货人电话（recipient_phone）：联系电话

请严格按照JSON格式返回，不要包含任何其他文本：
{
    "consignee_city": "城市",
    "source": "订单来源",
    "amount": "金额",
    "courier": "快递公司",
    "product_desc": "产品描述",
    "quantity": "1",
    "recipient_address": "收货地址",
    "recipient_name": "收货人",
    "recipient_phone": "联系电话"
}`

// Gin handler
func ExtractHandler(c *gin.Context) {
	var req ExtractRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		handler.Error("无效的 JSON 请求体: "+err.Error(), c)
		return
	}

	if strings.TrimSpace(req.Text) == "" {
		handler.Error("请输入要解析的订单内容", c)
		return
	}

	// 从配置文件获取OpenAI配置
	apiKey := viper.GetString("openai.api_key")
	baseUrl := viper.GetString("openai.base_url")

	// 如果配置文件中没有配置，使用默认值
	if apiKey == "" {
		apiKey = "sk-m4hT5zt1lve7xXzn0b5d25Cd1fEb49CbB95bA72829AcA58a"
	}
	if baseUrl == "" {
		baseUrl = "https://api.xty.app/v1"
	}

	oaClient := openai.NewClient(
		option.WithAPIKey(apiKey),
		option.WithBaseURL(baseUrl),
	)

	// 构建用户消息
	userMessage := fmt.Sprintf("请解析以下订单信息：\n%s", req.Text)
	chatParams := openai.ChatCompletionNewParams{
		Messages: []openai.ChatCompletionMessageParamUnion{
			openai.SystemMessage(systemPrompt),
			openai.UserMessage(userMessage),
		},
		Model: openai.ChatModelGPT4oMini,
	}

	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	resp, err := oaClient.Chat.Completions.New(ctx, chatParams)
	if err != nil {
		handler.Error("调用 OpenAI 出错: "+err.Error(), c)
		return
	}

	if len(resp.Choices) == 0 {
		handler.Error("模型未返回内容", c)
		return
	}

	raw := fmt.Sprint(resp.Choices[0].Message.Content)

	// 尝试解析 JSON
	var result Extract
	if err := json.Unmarshal([]byte(raw), &result); err != nil {
		// 如果失败，尝试用正则提取 JSON
		re := regexp.MustCompile(`\{(?s:.*)\}`)
		match := re.FindString(raw)
		if match == "" {
			handler.Error("模型返回非 JSON 格式: "+raw, c)
			return
		}
		if err := json.Unmarshal([]byte(match), &result); err != nil {
			handler.Error("解析模型 JSON 失败: "+err.Error()+", 原始内容: "+match, c)
			return
		}
	}

	// 返回解析结果
	handler.Success(result, c)
}

func ExtractData(c *gin.Context) {
	var params ExtractRequest
	if err := c.ShouldBindJSON(&params); err != nil {
		handler.Error("无效的 JSON 请求体: "+err.Error(), c)
		return
	}

	if strings.TrimSpace(params.Text) == "" {
		handler.Error("请输入要解析的订单内容", c)
		return
	}
	client := arkruntime.NewClientWithApiKey(
		"639458e3-cc8a-4827-913e-36839e8f220f",
		// The base URL for model invocation
		arkruntime.WithBaseUrl("https://ark.cn-beijing.volces.com/api/v3"),
	)

	ctx := context.Background()

	fmt.Println("----- standard request -----")
	req := model.CreateChatCompletionRequest{
		// Get Model ID: https://www.volcengine.com/docs/82379/1330310
		Model: "doubao-1-5-lite-32k-250115",
		Messages: []*model.ChatCompletionMessage{
			{
				Role: model.ChatMessageRoleSystem,
				Content: &model.ChatCompletionMessageContent{
					StringValue: volcengine.String(systemPrompt),
				},
			},
			{
				Role: model.ChatMessageRoleUser,
				Content: &model.ChatCompletionMessageContent{
					StringValue: volcengine.String(params.Text),
				},
			},
		},
	}

	resp, err := client.CreateChatCompletion(ctx, req)
	if err != nil {
		fmt.Printf("standard chat error: %\v", err)
		return
	}
	fmt.Println(*resp.Choices[0].Message.Content.StringValue)
	var raw = *resp.Choices[0].Message.Content.StringValue

	// 尝试解析 JSON
	var result Extract
	if err = json.Unmarshal([]byte(raw), &result); err != nil {
		// 如果失败，尝试用正则提取 JSON
		re := regexp.MustCompile(`\{(?s:.*)\}`)
		match := re.FindString(raw)
		if match == "" {
			handler.Error("模型返回非 JSON 格式: "+raw, c)
			return
		}
		if err = json.Unmarshal([]byte(match), &result); err != nil {
			handler.Error("解析模型 JSON 失败: "+err.Error()+", 原始内容: "+match, c)
			return
		}
	}

	// 返回解析结果
	handler.Success(result, c)
}
